<script setup lang="ts">
// import RenderComp from './renderComp.vue'
import {
  computed,
  defineEmits,
  defineExpose,
  defineProps,
  getCurrentInstance,
  onMounted,
  ref,
  toRefs,
  watch
} from "vue"
/**
 * @description 封装表格组件
 * @param {boolean} index 表格序号
 * @param {boolean} tableLoading 表格节流
 * @param { Array } tableData 数据源
 * @param {boolean} border 表格边框
 * @param { Array } tableColumns 表格列数据
 * @param {number} pageNum 页码
 * @param {number} pageSize 一页几条
 * @param {string} total 总条数
 * @param {boolean} selectionShow 表格多选  aSelection 值为选中的值 用ref直接可以取到
 * @param {boolean} redioShow 表格单选
 * @param {object} operates 操作列 {fixed:操作是否固定列,label:名称（默认操作）,list:[{label:'按钮名称'，type:按钮类型（默认text），methods：点击事件的方法（scope.row,index）}]}
 * @param { Function } handleSizeChange 分页
 * @param { Function } handleCurrentChange 翻页操作
 * @param { Function } selectable 仅对 type=selection 的列有效，类型为 Function，Function 的返回值用来决定这一行的 CheckBox 是否可以勾选
 * @param { String || Number} height Table 的高度，默认为自动高度。如果 height 为 number 类型，单位 px；如果 height 为 string 类型，则这个高度会设置为 Table 的 style.height 的值，Table 的高度会受控于外部样式。
 * @param {boolean} showTotal 是否展示下方分页 默认展示
 * @param {boolean} show 是否展示列
 * @param { Function } getRowKey 是否跨页选中
 */
import commonPaging from "./commonPaging.vue"

const props = defineProps({
  index: {
    type: Boolean,
    default: true
  },
  tableLoading: {
    type: Boolean,
    default: false
  },
  tableData: {
    type: Array,
    default() {
      return []
    }
  },
  border: {
    type: Boolean,
    default: false
  },
  tableColumns: {
    type: Array,
    default() {
      return []
    }
  },
  total: {
    type: [Number, String],
    default: 0
  },
  pageNum: {
    type: [Number, String],
    default: 1
  },
  pageSize: {
    type: [Number, String],
    default: 5
  },
  selectionShow: {
    type: Boolean,
    default: false
  },
  redioShow: {
    type: Boolean,
    default: false
  },
  operates: {
    type: Object,
    default() {
      return {}
    }
  },
  selectable: {
    type: Function,
    default() {
      return true
    }
  },
  height: {
    type: [Number, String],
    default: null
  },
  showTotal: {
    type: Boolean,
    default: true
  },
  rowClassName: {
    type: Function,
    default() {}
  },
  handleSizeChange: {
    type: Function,
    default() {}
  },
  handleCurrentChange: {
    type: Function,
    default() {}
  },
  getRowKey: {
    type: Function,
    default() {
      return null
    }
  }
})
// 分页组件
const emits = defineEmits<Emits>()
// 定义 emit 事件类型
interface Emits {
  (e: "row-click", row: any, column: any, event: Event): void
  (e: "tableColumnChangeSelect", val: any): void
  (e: "tableColumnChangeRadio", val: string): void
}
const redioVal = ref<string>("1")
const showLoading = ref<boolean>(false)
const aSelection = ref<any[]>([])
const multipleTable = ref<any>(null)
const tableColumn = computed(() => {
  return props.tableColumns.filter((item: any) => {
    // 传入参数无show 所以 undefined为真
    return item.show || item.show === undefined
  })
})

watch(
  () => props.tableLoading,
  (nVal, oVal) => {
    showLoading.value = nVal
    if (nVal === oVal) {
      return
    }
    if (nVal) {
      // 开启loading后 长时间未处理 去除loading
      setTimeout(() => {
        showLoading.value = false
      }, 20000)
    }
  },
  { deep: true }
)

function rowClick(row: any, column: any, event: Event) {
  // console.log(77, row.date)
  emits("rowClick", row, column, event)
}

function tableColumnChangeSelect(val: any) {
  aSelection.value = JSON.parse(JSON.stringify(val))
  emits("tableColumnChangeSelect", val)
}

function tableColumnChangeRadio(val: any) {
  redioVal.value = val // 单选事件赋值
  emits("tableColumnChangeRadio", val)
}

function clearSelection() {
  multipleTable.value.clearSelection()
}

function resetDateFilter(value: string) {
  multipleTable.value!.clearFilter([value])
}
// TODO: improvement typing when refactor table
function clearFilter() {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-expect-error
  multipleTable.value!.clearFilter()
}

defineExpose({ clearSelection, resetDateFilter, clearFilter })
// clearSelection
const { tableData, border, getRowKey, selectable, height, redioShow, total, pageNum, pageSize }
  = toRefs(props)
</script>

<template>
  <div class="table-common">
    <el-table
      ref="multipleTable"
      v-loading="showLoading"
      element-loading-text
      element-loading-background="rgba(255, 255, 255, 0.7)"
      :data="tableData"
      :border="border"
      style="width: 100%"
      :height="height"
      :row-class-name="rowClassName"
      @selection-change="tableColumnChangeSelect"
      @row-click="rowClick"
      :row-key="getRowKey"
      fit
      empty-text
    >
      <!-- 选择 -->
      <!-- 多选 -->
      <el-table-column
        v-if="selectionShow"
        type="selection"
        align="center"
        width="80"
        :selectable="selectable"
        :reserve-selection="true"
      />
      <!-- 单选 -->
      <el-table-column v-if="redioShow" :selectable="selectable" width="50">
        <template #default="scope">
          <el-radio
            v-model="redioVal"
            :label="scope.row"
            @change="tableColumnChangeRadio(scope.row)"
          >
            &nbsp;
          </el-radio>
        </template>
      </el-table-column>
      <!-- 序号 -->
      <el-table-column
        v-if="index"
        type="index"
        label="序号"
        width="80"
        align="center"
      >
        <template #default="scope">
          <span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
        </template>
      </el-table-column>
      <!-- 数据展示层 -->

      <el-table-column
        v-for="item in tableColumn"
        :key="item.prop"
        :align="item.align ? item.align : 'center'"
        :show-overflow-tooltip="item.tooltip"
        :prop="item.prop"
        :label="item.label"
        :width="item.width"
        :fixed="item.fixed"
        v-show="item.show"
      >
        <template #header>
          {{ item.label }}
        </template>
        <!-- 自定义插槽 -->
        <template #default="scope">
          <template v-if="item.slot">
            <slot
              :name="item.prop"
              :row="scope.row"
              :column="scope.column"
              :index="scope.$index"
            />
          </template>
          <template v-else>
            {{ scope.row[item.prop] ? scope.row[item.prop] : "--" }}
          </template>
        </template>
      </el-table-column>
      <!-- 操作 -->
      <el-table-column
        v-if="
          operates.hasOwnProperty('list')
            ? operates.list.filter((_x) => _x.show === true).length > 0
            : false
        "
        ref="fixedColumn"
        :align="operates.align || 'right'"
        :label="operates.label || '操作'"
        :fixed="operates.fixed"
        :width="operates.width || '120'"
      >
        <!-- align="left" -->
        <template #default="scope">
          <div class="operate-group">
            <template v-for="(btn, index) in operates.list">
              <span v-if="btn.show" :key="index" class="operate-btn">
                <el-button
                  :key="index"
                  size="small"
                  :type="btn.type || 'text'"
                  :disabled="btn.disabled"
                  @click="btn.methods(scope.row, index)"
                >{{ btn.label }}</el-button>
              </span>
            </template>
          </div>
        </template>
      </el-table-column>
      <template v-if="!showLoading && tableData.length === 0" #empty>
        <span>暂无数据</span>
      </template>
    </el-table>
    <common-paging
      v-if="(showTotal && total) || total < 0"
      :total="total"
      :page="pageNum"
      :size="pageSize"
      @handle-size-change="handleSizeChange"
      @handle-current-change="handleCurrentChange"
    />
  </div>
</template>
